﻿using System;
using System.Collections.Generic;
using System.Text;
using ExpressionUtil.Common;

namespace ExpressionUtil.Parser.Handler
{
    /// <summary>
    /// 逗号处理程序
    /// </summary>
    internal class CommaHandler : ParseHandlerBase
    {
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public CommaHandler()
        {
            this.next = new OperatorHandler();
        }

        /// <summary>
        /// 解析元素
        /// </summary>
        /// <param name="context">解析参数</param>
        /// <param name="element">需要解析的元素</param>
        /// <returns>是否已解析</returns>
        protected override bool ParseCore(string element, ParseContext context)
        {
            bool ret = false;
            if (element == ",")
            {
                this.CheckComma(context);
                ret = true;
                if (context.OperatorStack.Count > 0)
                {
                    this.ParseComma(context);
                }
                else
                {
                    throw new FormatException("Missing operand before comma.");
                }
            }
            return ret;
        }

        /// <summary>
        /// 解析处理逗号
        /// </summary>
        /// <param name="context">解析环境变量</param>
        private void ParseComma(ParseContext context)
        {
            string op = context.OperatorStack.Pop();
            while (!op.EndsWith("("))
            {
                CheckHelper.CreateHandlerExists(op, "Unknow operator.");
                ParseContext.CreateHandlerMap[op](context);
                if (context.OperatorStack.Count > 0)
                {
                    op = context.OperatorStack.Pop();
                }
                else
                {
                    throw new FormatException("Missing operand before comma.");
                }
            }
            context.OperatorStack.Push(op);
        }

        /// <summary>
        /// 检查逗号
        /// </summary>
        /// <param name="context">解析环境变量</param>
        private void CheckComma(ParseContext context)
        {
            char nextChar = context.Scanner.NextChar;
            if (nextChar == char.MaxValue || StringHelper.IsNoneUnitaryOperatorChar(nextChar) || nextChar == ',' || nextChar == ')')
            {
                throw new FormatException("Missing operand after comma.");
            }
        }
    }
}
